#pragma once

#include <simmgr.h>

class SimContact
{
public:
  TCHAR szName[MAX_LENGTH_PHONEBOOKENTRYTEXT];
  TCHAR szNumber[MAX_LENGTH_ADDRESS];
  DWORD simIndex;
  bool  isActive;

  SimContact() : simIndex(0), isActive(false)
  { szName[0] = 0; szNumber[0] = 0; }
};

class SimContactList
{
public:
  SimContactList() : items(NULL), count(0)
  {}
  ~SimContactList()
  { Clear(); }

  bool Create(long numItems);
  void Clear();

  long GetCount()
  { return count; }
  const SimContact* Get(long index)
  { if (index >= 0 && index < count) return &items[index]; else return NULL; }

  bool Add(DWORD simIndex, const TCHAR* szName, const TCHAR* szNumber);
  void Delete(DWORD simIndex);

  void Sort();

protected:
  long Find(DWORD simIndex);

private:
  SimContact* items;
  long count;
};

class SimManager
{
public:
  static bool Initialize(HWND hWindow, bool sendNotifications, bool delayedLoading);
  static void Terminate();

  static long GetContactsCount();
  static bool GetContact(long index, TCHAR* szName, size_t nName, TCHAR* szNumber, size_t nNumber);

  static long GetActiveContactsCount();
  static bool GetNextActiveContact(long& index, TCHAR* szName, size_t nName, TCHAR* szNumber, size_t nNumber);

  static void BeginLoading();

  static bool IsBusy()
  { return isBusy; }

private:
  // THREAD FUNCTIONS
  static void SimCallback(DWORD dwNotifyCode, const void* pData, DWORD dwDataSize, DWORD dwParam);
  static DWORD MainThread(LPVOID lpInstance);

  // SYNCHRONIZED FUNCTIONS
  static void SyncTerminate(bool terminate);
  static bool SyncIsTerminating();
  static void SyncSetBusy(bool busy);

  static bool SyncAddItem(DWORD simIndex, const TCHAR* szName, const TCHAR* szNumber);
  static void SyncDeleteItem(DWORD simIndex);
  static void SyncSortList();

private:
  static HWND   hWnd;
  static bool   isRunning;
  static bool   isTerminating;
  static bool   isBusy;
  static HANDLE hThread;
  static DWORD  dwThread;
  static bool   delayLoad;
  static bool   sendNotify;
  // sync
  static HANDLE           evtAction;
  static CRITICAL_SECTION csSync;
  // sim
  static HSIM           hSim;
  static SimContactList simList;
};